feat: Replace mobile logo grid with infinite scrolling marquee#2875
feat: Replace mobile logo grid with infinite scrolling marquee#2875
Conversation
On mobile (below sm breakpoint), the enterprise logo grid is now replaced with a horizontally scrolling marquee that shows all logos in a continuous loop, matching the HeroStatsStrip animation pattern. - All logos are visible on mobile (previously only 6 of 12 shown) - Uses framer-motion for smooth infinite horizontal scroll - Gradient mask fades edges for seamless visual loop - Desktop grid layout (sm and above) remains unchanged - Slightly smaller logos (40px vs 56px) in marquee for better fit Resolves MKT-2060 Co-authored-by: felixkrrr <felixkrrr@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Co-authored-by: felixkrrr <felixkrrr@users.noreply.github.com>
Co-authored-by: felixkrrr <felixkrrr@users.noreply.github.com>
- Increase marquee logo height from 40px to 48px - Fix padding override so !py-0 !px-1 properly eliminates the default LinkBox padding (py-1.25 px-4.5) that was creating oversized hit boxes around each logo Co-authored-by: felixkrrr <felixkrrr@users.noreply.github.com>
The SVG logos have large whitespace margins within their 140x40 viewBox. In the marquee, use negative horizontal margin (-mx-[20px]) on the images with overflow-hidden wrapper to visually crop the side whitespace, making logos appear larger and sit closer together. Co-authored-by: felixkrrr <felixkrrr@users.noreply.github.com>
Render logos at full 56px height (same as desktop) but crop to a 32px visible area with overflow-hidden. Negative margins on all sides (-mx-22px, -my-12px) trim the whitespace baked into the SVG viewBoxes, making the actual logo content appear much larger and tightly packed. Co-authored-by: felixkrrr <felixkrrr@users.noreply.github.com>
Increase image from 56px to 72px, visible container from 32px to 44px, and adjust crop margins (-mx-28px, -my-14px) to keep the whitespace trimmed while showing logos at a larger size. Co-authored-by: felixkrrr <felixkrrr@users.noreply.github.com>
Replace negative-margin cropping approach with scale-150 transform which reliably scales up the logo content by 50%. Container is 44px tall with overflow-hidden and flex items-center to vertically center the scaled logos. Co-authored-by: felixkrrr <felixkrrr@users.noreply.github.com>
- Scale down from 150% to 125% - Remove all padding on marquee LinkBoxes (!p-0) for tighter spacing Co-authored-by: felixkrrr <felixkrrr@users.noreply.github.com>
… gaps Apply -mx-5 on each logo's overflow-hidden wrapper to overlap the SVG's baked-in horizontal whitespace, pulling logos much closer together in the mobile marquee. Co-authored-by: felixkrrr <felixkrrr@users.noreply.github.com>
|
@claude review |
Mark the second copy of LogoMarqueeItems with aria-hidden='true' so assistive technology doesn't announce every logo twice. Addresses PR review comment from greptile. Co-authored-by: felixkrrr <felixkrrr@users.noreply.github.com>
- Replace aria-hidden='true' with inert on the duplicate marquee wrapper so focusable links are also removed from tab order (P1) - Remove dead grid-cols-3 class from desktop grid wrapper - Remove unused Fragment import Co-authored-by: felixkrrr <felixkrrr@users.noreply.github.com>
- Use useReducedMotion() from framer-motion to disable the marquee animation when the user has prefers-reduced-motion enabled, addressing WCAG 2.2.2 (Pause, Stop, Hide, Level A). - Remove role='marquee' from the mobile wrapper — the DOM content is static (only CSS transforms animate), so the live-region role is semantically incorrect. Matches HeroStatsStrip pattern. Co-authored-by: felixkrrr <felixkrrr@users.noreply.github.com>
- Replace inert wrapper with per-LinkBox aria-hidden/tabIndex on the duplicate copy. The inert attribute blocked all interaction (clicks/taps) on the duplicate logos, which are visible ~50% of the marquee cycle. Now duplicate links remain clickable but are hidden from AT and removed from tab order. - When prefers-reduced-motion is enabled, render a horizontally scrollable row (overflow-x-auto, single copy, hidden scrollbar) instead of the animated marquee. Previously the animation was just disabled, leaving logos clipped by overflow-hidden with no way to reach them. Co-authored-by: felixkrrr <felixkrrr@users.noreply.github.com>
There was a problem hiding this comment.
Author iterated through accessibility feedback and the current revision applies the recommended fixes (per-item aria-hidden/tabIndex on the duplicate copy, branched JSX for reduced motion); LGTM.
Extended reasoning...
Overview
This PR replaces the mobile 3-column logo grid with a framer-motion-powered horizontal marquee on components/shared/EnterpriseLogoGrid.tsx, while keeping the desktop 6-column grid unchanged. The current revision is the result of several review iterations addressing accessibility concerns (duplicate-content announcements, keyboard tab order, reduced-motion handling, semantic role usage, dead code).
Security risks
None. This is a presentational marketing component on a public landing page — no auth, no user input, no data flow, no network calls beyond the existing static logo image imports. The framer-motion dependency was already in use elsewhere in the codebase (e.g. HeroStatsStrip, FeatureTabs).
Level of scrutiny
Moderate — the PR is small (~80 lines net) and self-contained, but a11y nuances around marquee patterns warranted careful review. After multiple iterations, the current implementation correctly:
- Uses per-
LinkBoxaria-hidden/tabIndex={-1}on the duplicate copy (avoids botharia-hidden-on-focusable-content andinert-blocks-clicks pitfalls) - Branches to an
overflow-x-autoscrollable fallback whenuseReducedMotion()is true (avoids clipping content) - Drops the misleading
role="marquee" - Cleans up unused imports and dead Tailwind utilities
Other factors
The author has been highly responsive across multiple review cycles, addressing every previously-raised critical issue with the suggested fix shape. Greptile's open nit on the -mx-5 negative margin in the compact image wrapper is minor (potential adjacent-logo bleed under tight packing) and not blocking. No bug-hunter findings on the current revision.
Summary
Resolves MKT-2060 — On mobile, the enterprise logo section below the hero now displays as a single-row infinite scrolling marquee (matching the HeroStatsStrip animation pattern above the hero title), instead of a 3-column grid that hid most logos.
Changes
components/shared/EnterpriseLogoGrid.tsxsm): Replaced the 3-column grid with a horizontally scrolling marquee powered byframer-motion. All 12 visible logos now appear in a continuous loop with gradient edge masks for seamless visual wrapping.smand above): The existing 6-column grid layout is preserved unchanged.HeroStatsStrip(duplicate content,x: ["0%", "-50%"]animation, linear easing, edge gradient mask).Before / After
Linear Issue: MKT-2060
Disclaimer: Experimental PR review
Greptile Summary
This PR replaces the mobile enterprise logo section from a 3-column grid (showing only 6 logos) with a
framer-motion-powered infinite scrolling marquee that shows all 12 visible logos, while preserving the existing 6-column desktop grid. The implementation correctly handles theprefers-reduced-motionpreference with a static horizontal-scroll fallback, and properly marks duplicate marquee items witharia-hiddenandtabIndex=-1.Confidence Score: 5/5
Safe to merge — the change is additive and isolated to a single marketing component with no data or auth implications.
Only P2 findings (a brief flash of animation for reduced-motion users on initial render). No P0/P1 issues found. Desktop layout is fully preserved.
No files require special attention.
Important Files Changed
useReducedMotion()returnsnullon initial render, so the animated version is briefly shown before the preference is applied.Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[EnterpriseLogoGrid] --> B{Viewport} B -->|Mobile below sm| C{shouldReduceMotion} B -->|Desktop sm and above| D[Static 6-col grid\nall visibleCompanies] C -->|true or null| E[Static overflow-x-auto scroll\nLogoMarqueeItems once] C -->|false| F[motion.div animated marquee\nx: 0% to -50%] F --> G[LogoMarqueeItems primary] F --> H[LogoMarqueeItems duplicate\naria-hidden tabIndex=-1]Prompt To Fix All With AI
Reviews (3): Last reviewed commit: "a11y: fix inert blocking clicks + add re..." | Re-trigger Greptile